from app.extensions import db
from datetime import datetime
from app.models.model_mixin import BaseMixin


class Category(db.Model, BaseMixin):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(20))
    pid = db.Column(db.Integer, db.ForeignKey('category.id'), default=None)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow)

    children = db.relationship('Category', backref=db.backref('parent', remote_side=[id]))
    articles = db.relationship('Article', back_populates='category')

    @staticmethod
    def tree():
        tree_dict = []
        data = Category.query.filter_by(pid=None).all()

        def get_tree(tree_root, tree_dict, level=0):
            if not tree_root.children:
                return

            level += 1
            for child in tree_root.children:
                tree_dict.append({
                    'id': child.id,
                    'title': child.title,
                    'level': level,
                    'created_at': child.created_at,
                    'updated_at': child.updated_at
                })
                get_tree(child, tree_dict, level)

        for item in data:
            tree_dict.append({
                'id': item.id,
                'title': item.title,
                'level': 0,
                'created_at': item.created_at,
                'updated_at': item.updated_at
            })
            get_tree(item, tree_dict)

        return tree_dict

    def to_dict(self):
        return {
            'id': self.id,
            'title': self.title
        }

    @staticmethod
    def to_collection_dict(query, page, per_page=10):
        resources = query.paginate(page, per_page, False)
        data = {
            'items': [item.to_dict() for item in resources.items],
            '_meta': {
                'page': page,
                'per_page': per_page,
                'total_pages': resources.pages,
                'total_items': resources.total
            }
        }
        return data
